require "yaml"

class BenchmarkResult

  include Enumerable

  def initialize(all)
    @all = YAML.load_file(all).map{|name, y| Item.new(name, y) }.sort_by {|e| e.key }
  end

  def each(&block)
    @all.each(&block)
  end

  def result(target)
    self.map{|e| [e.interpreter, e.library, e.wallclock(target)] }
  end

  def scripts
    self.map{|e| [e.name, e.lang, e.script] }
  end

  class Item
    attr_reader :name, :y

    def initialize(name, result)
      @name = name
      @y = result
    end

    def key
      [lang, interpreter, library].join
    end

    def script
      y["benchmark_script"]
    end

    def lang
      y["language"]
    end

    def interpreter
      r = name_version(y["interpreter"])
      r << " / " << runtime if runtime?
      r
    end

    def library
      r	 = name_version(y["library"])
      r	 << " / " << native_library if native?
      r	
    end

    def native_library
      name_version(y["library"]["native_library"])
    end

    def native?
      Hash === y["library"]["native_library"]
    end

    def runtime
      name_version(y["interpreter"]["runtime"])
    end

    def runtime?
      Hash === y["interpreter"]["runtime"]
    end

    def wallclock(target)
      unless y["result"][target]
        warn "benchmark result for `#{target}' not found."
        return nil
      end
      r = y["result"][target]["wallclock"]
      if base = y["result"][target]["base"]
        r /= base.to_f
      end
      r
    end

    def name_version(y)
      %W(name version).map{|e| y[e] }.join(" ")
    end
    private :name_version

  end
end
